package com.view;

import android.content.Context;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.widget.RelativeLayout;

import com.hcvsa.CloseAVChannel;
import com.hcvsa.MyHCVSA;
import com.hcvsa.OpenAVChannel;
import com.squareup.otto.Subscribe;
import com.until.BusProvider;
import com.until.LogUnti;
import com.vmcmonitor.common.CameraSurface;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import androidx.annotation.RequiresApi;
import fun.flyee.android.pengshan.events.StartAudioRecordEvent;
import fun.flyee.android.pengshan.events.StopAudioRecordEvent;
import fun.flyee.android.pengshan.utils.Logger;
import fun.flyee.android.pengshan.utils.Systems;
import fun.flyee.android.pengshan.utils.Util;
import hcvs.camera.ICameraSurface;
import hcvs.hcvca.bean.MonitorWindow;
import hcvs.hcvsa.TPEvent;
import hcvs.opengl.util.CameraGLSurface;
import hcvs.videorender.VideoPlayLayout;

public class MyVideoRel2 extends RelativeLayout {

    /**
     * 编码方式  硬编码
     */
    private int encodeType = CameraSurface.VIDEO_HARDWARE_ENCODE;
    /**
     * 视频码率
     */
    private int currentCodeRate = 512;
    /**
     * 前置摄像头
     */
    private int currentCameraFacing = Camera.CameraInfo.CAMERA_FACING_FRONT;
    /**
     * 视频清晰度
     */
    private int currentdefinition = CameraSurface.VIDEO_DEFINITION_720P;
    /**
     * 视频偏转角度
     */
    private int currentCameraDeflection = 0;

    private Context mContext;
    private List<SurfaceView> myTPSurfaceViewList = new ArrayList<>();
    /*画中画比例*/
    private int scale = 16;
    /*全屏的surfaceView*/
    private View fullScreenSurfaceView;
    private VideoPlayLayout videoPlayLayout;
    //是否只显示小画面
    private boolean isSmallLayout = false;
    //是否只启用通道0，视频通话时只启用通道0
    private boolean isOnlyChannel0 = false;
    private MyHandler mHandler = new MyHandler();
    private OnRemoteChannel onRemoteChannel;
    private boolean isOpenMyVideo = true;

    public boolean isOpenMyVideo() {
        return isOpenMyVideo;
    }

    public void setOpenMyVideo(boolean openMyVideo) {
        isOpenMyVideo = openMyVideo;
    }

    public MyVideoRel2(Context context) {
        super(context);
        init(context);
    }

    public MyVideoRel2(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public MyVideoRel2(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public void release() {
        BusProvider.getInstance().post(new StopAudioRecordEvent());
        removeAllView();
        MyHCVSA.getInstance().CloseMyVideoChannel();
        BusProvider.getInstance().unregister(this);
//        MyHCVSA.getInstance().setWhiteBoardEventListner(null);

    }

    private void init(Context context) {
        this.mContext = context;
        videoPlayLayout = new VideoPlayLayout();
        BusProvider.getInstance().register(this);
//        MyHCVSA.getInstance().setWhiteBoardEventListner(this);

    }

    class MyHandler extends Handler {

        MyHandler() {
        }

        MyHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {

            }
            super.handleMessage(msg);
        }
    }


    private class SurfaceOntouch implements OnTouchListener {
        boolean isMove;
        //开始触控的坐标，移动时的坐标（相对于屏幕左上角的坐标）
        private int mTouchStartX, mTouchStartY, mTouchCurrentX, mTouchCurrentY;
        //开始时的坐标和结束时的坐标（相对于自身控件的坐标）
        private int mStartX, mStartY, mStopX, mStopY;

        //双击事件变量
        int count = 0;
        long firClick = 0;
        long secClick = 0;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isMove = false;
                    mTouchStartX = (int) event.getRawX();
                    mTouchStartY = (int) event.getRawY();
                    mStartX = (int) event.getRawX();
                    mStartY = (int) event.getRawY();
//                    sdf((SurfaceView) v);
                    break;
                case MotionEvent.ACTION_MOVE:
                    mTouchCurrentX = (int) event.getRawX();
                    mTouchCurrentY = (int) event.getRawY();
                    LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
                    layoutParams.leftMargin += (mTouchCurrentX - mTouchStartX);
                    layoutParams.topMargin += (mTouchCurrentY - mTouchStartY);
                    //不能超出边界
                    if (layoutParams.leftMargin < 0)
                        layoutParams.leftMargin = 0;
                    if (layoutParams.topMargin < 0)
                        layoutParams.topMargin = 0;
                    if (layoutParams.leftMargin > (MyVideoRel2.this.getMeasuredWidth() - v.getMeasuredWidth()))
                        layoutParams.leftMargin = MyVideoRel2.this.getMeasuredWidth() - v.getMeasuredWidth();
                    if (layoutParams.topMargin > (MyVideoRel2.this.getMeasuredHeight() - v.getMeasuredHeight()))
                        layoutParams.topMargin = MyVideoRel2.this.getMeasuredHeight() - v.getMeasuredHeight();
                    v.setLayoutParams(layoutParams);
                    mTouchStartX = mTouchCurrentX;
                    mTouchStartY = mTouchCurrentY;
                    break;
                case MotionEvent.ACTION_UP:
                    mStopX = (int) event.getRawX();
                    mStopY = (int) event.getRawY();
                    if (Math.abs(mStartX - mStopX) >= 1 || Math.abs(mStartY - mStopY) >= 1) {
                        isMove = true;
//                        SurfaceView surfaceView = getSurfaceViewByPoint((int)event.getX(), (int)event.getY());
                        View surfaceView = getSurfaceViewByPoint(mStopX, mStopY, v);
                        if (surfaceView != null) {//交换两个布局的位置
                            if (surfaceView != v) {
                                Collections.swap(myTPSurfaceViewList, myTPSurfaceViewList.indexOf(surfaceView), myTPSurfaceViewList.indexOf(v));
                            }
                        }
                        updateUI();
                    } else {
                        //点击事件
                        if (myVideoPlayLinstener != null) {
                            SurfaceView surfaceView = getSurfaceViewByPoint(mStopX, mStopY, (SurfaceView) v);
                            myVideoPlayLinstener.OnViewClick(surfaceView);
                        }
                        count++;
                        if (count == 1) {
                            firClick = System.currentTimeMillis();
                        } else if (count == 2) {
                            secClick = System.currentTimeMillis();
                            if (secClick - firClick < 500) {
                                //双击事件
                                count = 0;
                                firClick = 0;
                                secClick = 0;
                                if (fullScreenSurfaceView == v) {
                                    fullScreenSurfaceView = null;
                                } else {
                                    fullScreenSurfaceView = (SurfaceView) v;
                                }
                                updateUI();
                            } else {
                                count = 1;
                                firClick = secClick;
                                secClick = 0;
                            }
                        }
                        return false;
                    }
                    break;
            }
            return true;
        }
    }

    private void addListener(final SurfaceView surfaceView) {
        surfaceView.setOnTouchListener(new SurfaceOntouch());
    }


    /**
     * 根据传入的x，y坐标，获取对应的surfaceView
     *
     * @param endX
     * @param endY
     * @param currentSurfaceView 当前surfaceView，如果是自己则不处理
     * @return
     */
    private SurfaceView getSurfaceViewByPoint(int endX, int endY, View currentSurfaceView) {
        for (int i = 0; i < myTPSurfaceViewList.size(); i++) {
            SurfaceView surfaceView = myTPSurfaceViewList.get(i);
            if (surfaceView == currentSurfaceView)
                continue;
            int left = surfaceView.getLeft();
            int right = surfaceView.getRight();
            int top = surfaceView.getTop();
            int bottom = surfaceView.getBottom();

            if (endX >= left && endX <= right && endY >= top && endY <= bottom) {
                return surfaceView;
            }
        }
        return null;
    }

    //打开我的视频
    public SurfaceView openMyCarmera(int channel) {
        //只支持两个通道
        if (channel != 0 && channel != 1)
            return null;

        //判断是否已经打开了，打开了则不处理
        for (int i = 0; i < myTPSurfaceViewList.size(); i++) {
            View surfaceView = myTPSurfaceViewList.get(i);
            //打开了则不处理
            if (surfaceView instanceof CameraSurface) {
                CameraSurface cameraSurface = (CameraSurface) surfaceView;
                if (cameraSurface.m_nChannel == channel)
                    return null;
            }
        }

        CameraGLSurface cameraSurface = new CameraGLSurface(mContext,
                encodeType,
                currentCodeRate,
                currentCameraDeflection,
                currentCameraFacing,
//                CameraSurface.CAMERA_FACING_USB,
                currentdefinition);
        cameraSurface.create();
        MyVideoRel2.this.addView(cameraSurface);
        myTPSurfaceViewList.add(cameraSurface);
        addListener(cameraSurface);
        //我的视频为全屏
        fullScreenSurfaceView = cameraSurface;
        updateUI();
        if (myVideoPlayLinstener != null) {
            myVideoPlayLinstener.OnOpenMyCamera(cameraSurface);
        }
        return cameraSurface;
    }

    public List<SurfaceView> getMyTPSurfaceViewList() {
        return myTPSurfaceViewList;
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Subscribe
    public void OpenAVChannel(OpenAVChannel data) {
        if (myTPSurfaceViewList != null) {
            for (SurfaceView view : myTPSurfaceViewList) {
                if (view instanceof MyTPSurfaceView) {
                    MyTPSurfaceView tSView = (MyTPSurfaceView) view;
                    if (tSView.getmId() == data.getId()) {
                        return;
                    }
                }
            }
        }
        LogUnti.d("OpenAVChannel 222 type = " + data.getType());
        if (data.getType() != TPEvent.HCVS_CHANNEL_USER
                && data.getType() != TPEvent.HCVS_CHANNEL_MY
                && data.getType() != TPEvent.HCVS_CHANNEL_TP
                && data.getType() != TPEvent.HCVS_CHANNEL_DEVICE
                && data.getType() != TPEvent.HCVS_CHANNEL_MEETING
                && data.getType() != TPEvent.HCVS_CHANNEL_MEETING_VTDU
//                && data.getType() != TPEvent.HCVS_TYPE_DESKTOP_CHANNEL
        )
            return;

        //如果是会议室的扩展通道，必须先判断是否已经打开。
        if (data.getType() == TPEvent.HCVS_CHANNEL_MEETING && data.getChannel() == 1) {
            if (MyHCVSA.getInstance().getMeetingMoudle().IsOpenMeetingExtChannel() == false)
                return;
        }

        if (data.getType() == TPEvent.HCVS_CHANNEL_USER
                || data.getType() == TPEvent.HCVS_CHANNEL_TP
                || data.getType() == TPEvent.HCVS_CHANNEL_DEVICE
                || data.getType() == TPEvent.HCVS_CHANNEL_MEETING
                || data.getType() == TPEvent.HCVS_CHANNEL_MEETING_VTDU
//                || data.getType() == TPEvent.HCVS_TYPE_DESKTOP_CHANNEL
        ) {//打开用户的视频
            final MyTPSurfaceView myTPSurfaceView = new MyTPSurfaceView(mContext, data.getpVideoData());
            myTPSurfaceView.setType(data.getType());
            myTPSurfaceView.setmId(data.getId());
            myTPSurfaceView.setChannel(data.getChannel());
            this.addView(myTPSurfaceView);
            myTPSurfaceViewList.add(myTPSurfaceView);
            addListener(myTPSurfaceView);

            if (onRemoteChannel != null) {
                onRemoteChannel.onOpenAVChannel(data);
            }

            if (myVideoPlayLinstener != null) {
                myVideoPlayLinstener.OnNewSurfaceAdded(myTPSurfaceView);
            }

            if (data.getType() == TPEvent.HCVS_CHANNEL_MEETING) {
                fullScreenSurfaceView = myTPSurfaceView;
            }

            if (data.getType() == TPEvent.HCVS_CHANNEL_USER) {
                fullScreenSurfaceView = myTPSurfaceView;
            }

            if (data.getType() == TPEvent.HCVS_CHANNEL_TP) {
                fullScreenSurfaceView = myTPSurfaceView;
            }

//            if (data.getType() == TPEvent.HCVS_TYPE_DESKTOP_CHANNEL){
//                fullScreenSurfaceView = myTPSurfaceView;
//            }


        } else if (data.getType() == TPEvent.HCVS_CHANNEL_MY) {//打开自己的视频
            if (isOpenMyVideo) {
                //打开自己的视频
                openMyCarmera(data.getChannel());
            }
            //音频采集初始化
            BusProvider.getInstance().post(new StartAudioRecordEvent(data.getChannel()));
        }
        updateUI();
    }

    @Subscribe
    public void CloseAVChannel(CloseAVChannel data) {
        LogUnti.d("CloseAVChannel type = " + data.getType());
        if (data.getType() != TPEvent.HCVS_CHANNEL_USER
                && data.getType() != TPEvent.HCVS_CHANNEL_MY
                && data.getType() != TPEvent.HCVS_CHANNEL_DEVICE
                && data.getType() != TPEvent.HCVS_CHANNEL_TP
                && data.getType() != TPEvent.HCVS_CHANNEL_MEETING
//                && data.getType() != TPEvent.HCVS_TYPE_DESKTOP_CHANNEL
        )
            return;

        for (int i = 0; i < myTPSurfaceViewList.size(); i++) {
            SurfaceView surfaceView = myTPSurfaceViewList.get(i);
            /*如果关闭了当前全屏的surfaceview，则取消该全屏*/
            if (surfaceView == fullScreenSurfaceView)
                fullScreenSurfaceView = null;

            //对方的视频
            if (surfaceView instanceof MyTPSurfaceView) {
                MyTPSurfaceView myTPSurfaceView = (MyTPSurfaceView) surfaceView;
                if (myTPSurfaceView.getType() == data.getType()
                        && myTPSurfaceView.getmId() == data.getId()
                        && myTPSurfaceView.getChannel() == data.getChannel()
                ) {
                    this.removeView(myTPSurfaceView);
                    myTPSurfaceViewList.remove(myTPSurfaceView);
                    myTPSurfaceView = null;
                    break;
                }
            }

            //自己的视频
            if (surfaceView instanceof CameraGLSurface && data.getType() == TPEvent.HCVS_CHANNEL_MY) {
                CameraGLSurface cameraSurface = (CameraGLSurface) surfaceView;
                if (cameraSurface.getChannel() != data.getChannel())
                    continue;

                cameraSurface.destory();
                this.removeView(cameraSurface);
                myTPSurfaceViewList.remove(cameraSurface);
                cameraSurface = null;
                break;
            }
        }
        if (data.getType() == TPEvent.HCVS_CHANNEL_MY) {
            Logger.e("release audio in view");
            BusProvider.getInstance().post(new StopAudioRecordEvent());
        }
        updateUI();

    }

    private void removeAllView() {
        for (View myTPSurfaceView : myTPSurfaceViewList) {
            if (myTPSurfaceView instanceof CameraSurface) {
                CameraSurface cameraSurface = (CameraSurface) myTPSurfaceView;
                cameraSurface.unInit();
            }
            this.removeView(myTPSurfaceView);
            myTPSurfaceViewList.remove(myTPSurfaceView);
            myTPSurfaceView = null;
            System.gc();
        }
    }

    private int margin = 0;
    private int padding = 0;

    public void updateUI() {

        //如果没有全屏的窗口，则按规则排列
        if (fullScreenSurfaceView == null) {
            if (isSmallLayout) {
                updateUISmall();
            } else {
                updateUINormal();
            }
        } else {
            //画中画
            if (true) {
                updateUIPicInPic();
            } else {//非画中画
                updateUINotPicInPic();
            }
        }

//        this.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
    }

    /**
     * 切换下一个布局
     */
    public void nextLayout() {
        if (myTPSurfaceViewList.size() <= 0)
            return;
        //如果已经是最后一个全屏窗口了，则将关闭全屏
        if (fullScreenSurfaceView == myTPSurfaceViewList.get(myTPSurfaceViewList.size() - 1)) {
            fullScreenSurfaceView = null;
        } else if (fullScreenSurfaceView == null) {//如果全屏窗口等于空，则将第一个窗口全屏
            fullScreenSurfaceView = myTPSurfaceViewList.get(0);
        } else {
            for (int i = 0; i < myTPSurfaceViewList.size(); i++) {
                View surfaceView = myTPSurfaceViewList.get(i);
                if (surfaceView == fullScreenSurfaceView) {//设置下一个为全屏窗口
                    fullScreenSurfaceView = myTPSurfaceViewList.get(i + 1);
                    break;
                }
            }
        }
        updateUI();
    }

    int i = 0;

    //全屏画中画
    private void updateUIPicInPic() {
        if (fullScreenSurfaceView == null)
            return;
        int width = getMeasuredWidth() / scale;
        int height = getMeasuredHeight() / scale;
        width = Util.dp2px(getContext(), 120);
        height = width * 16 / 9;
        //全屏窗口的总数
        int fullScreenCount = 0;
        for (int i = 0; i < myTPSurfaceViewList.size(); i++) {
            View view = myTPSurfaceViewList.get(i);
            if (view instanceof SurfaceView) {
                SurfaceView surfaceView = (SurfaceView) view;
                if (surfaceView == fullScreenSurfaceView) {
                    surfaceView.setZOrderOnTop(false);
                    surfaceView.setZOrderMediaOverlay(false);
//                surfaceView.setElevation(0f);
//                    LayoutParams layoutParams = new LayoutParams(width, height);
                    LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
                    surfaceView.setLayoutParams(layoutParams);
                    fullScreenCount++;
                } else {
                    surfaceView.setZOrderOnTop(true);
                    surfaceView.setZOrderMediaOverlay(true);
//                surfaceView.setElevation(10f);
//                    Log.i("videosize", width + " X " + height);
                    LayoutParams layoutParams = new LayoutParams(width, height);
                    layoutParams.topMargin = ((i - fullScreenCount) % scale) * height;
                    layoutParams.leftMargin = (getMeasuredWidth() - (width * ((i - fullScreenCount) / scale)));
                    layoutParams.leftMargin -= width;//减掉自己的宽度
                    surfaceView.setLayoutParams(layoutParams);
                }
            } else {

            }

        }
    }

    //全屏非画中画
    private void updateUINotPicInPic() {
        if (fullScreenSurfaceView == null)
            return;
        //全屏窗口的总数
        for (int i = 0; i < myTPSurfaceViewList.size(); i++) {
            View surfaceView = myTPSurfaceViewList.get(i);
            if (surfaceView == fullScreenSurfaceView) {
                LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
                fullScreenSurfaceView.setLayoutParams(layoutParams);
            } else {
                LayoutParams layoutParams = new LayoutParams(0, 0);
                surfaceView.setLayoutParams(layoutParams);
            }
        }
    }

    //小图像布局
    private void updateUISmall() {
        int width = getMeasuredWidth() / scale;
        int height = getMeasuredHeight() / scale;
        //要改变一下宽度和高度，才能刷新Z轴位置，暂时没搞懂为什么
        width += 1;
        height += 1;
        int fullScreenCount = 0;

        for (int i = 0; i < myTPSurfaceViewList.size(); i++) {
            View surfaceView = myTPSurfaceViewList.get(i);
            LayoutParams layoutParams = new LayoutParams(width, height);
            layoutParams.topMargin = ((i - fullScreenCount) % scale) * height;
            layoutParams.leftMargin = (getMeasuredWidth() - (width * ((i - fullScreenCount) / scale)));
            layoutParams.leftMargin -= width;//减掉自己的宽度
            surfaceView.setLayoutParams(layoutParams);
        }
    }

    //正常布局UI
    private void updateUINormal() {
        //总的投屏个数
        int viewCount = myTPSurfaceViewList.size();
        if (viewCount <= 0) {
            return;
        } else if (viewCount == 1) {
            videoPlayLayout.setVmlByKey(VideoPlayLayout.VIDEO_LAYOUT_1x1);
        } else if (viewCount == 2) {
            videoPlayLayout.setVmlByKey(VideoPlayLayout.VIDEO_LAYOUT_2x1);
        } else if (viewCount <= 4) {
            videoPlayLayout.setVmlByKey(VideoPlayLayout.VIDEO_LAYOUT_2x2);
        } else if (viewCount <= 9) {
            videoPlayLayout.setVmlByKey(VideoPlayLayout.VIDEO_LAYOUT_3x3);
        } else {
            videoPlayLayout.setVmlByKey(VideoPlayLayout.VIDEO_LAYOUT_4x4);
        }

        ArrayList<MonitorWindow> monitorWindows = videoPlayLayout.getWindow(getMeasuredWidth(), getMeasuredHeight());
        if (myTPSurfaceViewList.size() > monitorWindows.size()) {
            for (int i = monitorWindows.size(); i < myTPSurfaceViewList.size(); i++) {
                myTPSurfaceViewList.get(i).setVisibility(View.GONE);
            }
        }

        for (int i = 0; i < monitorWindows.size(); i++) {
            if (i >= myTPSurfaceViewList.size()) continue;

            MonitorWindow monitorWindow = monitorWindows.get(i);
            Rect rect = monitorWindow.getRect();
            int width = rect.right - rect.left - margin;
            int height = rect.bottom - rect.top - margin;
            int x = rect.left + padding;
            int y = rect.top + padding;

            LayoutParams layoutParams = new LayoutParams(width, height);
            layoutParams.leftMargin = x;
            layoutParams.topMargin = y;
            myTPSurfaceViewList.get(i).setLayoutParams(layoutParams);
        }
    }

    public boolean isSmallLayout() {
        return isSmallLayout;
    }

    public void setSmallLayout(boolean smallLayout) {
        isSmallLayout = smallLayout;
    }


    public ICameraSurface getCameraSurface(int channel) {
        for (int i = 0; i < myTPSurfaceViewList.size(); i++) {
            View surfaceView = myTPSurfaceViewList.get(i);
            if (surfaceView instanceof ICameraSurface) {
                ICameraSurface cameraSurface = (ICameraSurface) surfaceView;
                if (cameraSurface.getChannel() == channel) {
                    return cameraSurface;
                }
            }
        }
        return null;
    }

    public boolean isOnlyChannel0() {
        return isOnlyChannel0;
    }

    public void setOnlyChannel0(boolean onlyChannel0) {
        isOnlyChannel0 = onlyChannel0;
    }

    private MyVideoPlayLinstener myVideoPlayLinstener;

    public interface MyVideoPlayLinstener {
        void OnNewSurfaceAdded(SurfaceView surfaceView);

        void OnOpenMyCamera(ICameraSurface cameraSurface);

        void OnViewClick(SurfaceView surfaceView);
    }

    public MyVideoPlayLinstener getMyVideoPlayLinstener() {
        return myVideoPlayLinstener;
    }

    public void setMyVideoPlayLinstener(MyVideoPlayLinstener myVideoPlayLinstener) {
        this.myVideoPlayLinstener = myVideoPlayLinstener;
    }

    public void setOnRemoteChannel(OnRemoteChannel onRemoteChannel) {
        this.onRemoteChannel = onRemoteChannel;
    }

    public interface OnRemoteChannel {
        void onOpenAVChannel(OpenAVChannel happen);
    }
}